package com.eastfair.venueservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.builder.dto.ExhibitorDTO;
import com.eastfair.builder.vo.ExhibitorVO;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.venuebooking.vo.ExhibitionSpaceVO;
import com.eastfair.venueservice.dao.ServiceProviderSpaceMapper;
import com.eastfair.venueservice.dto.ServiceProviderSpaceDTO;
import com.eastfair.venueservice.dto.ServiceProviderSpaceQuery;
import com.eastfair.venueservice.entity.ExhibitionManage;
import com.eastfair.venueservice.entity.ExhibitionServiceProvider;
import com.eastfair.venueservice.entity.ServiceProvider;
import com.eastfair.venueservice.entity.ServiceProviderSpace;
import com.eastfair.venueservice.enumeration.ServiceProviderTypeEnum;
import com.eastfair.venueservice.service.*;
import com.eastfair.venueservice.vo.ServiceProviderSpaceVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 展会服务商场地关系
 * </p>
 *
 * @author linan
 * @date 2022-07-15
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class ServiceProviderSpaceServiceImpl extends SuperServiceImpl<ServiceProviderSpaceMapper, ServiceProviderSpace> implements ServiceProviderSpaceService {

    @Resource
    private ExhibitionServiceProviderService exhibitionServiceProviderService;

    @Resource
    private ExhibitionManageService exhibitionManageService;

    @Resource
    private ServiceProviderService serviceProviderService;

    @Resource
    private VenueManageExhibitionSpaceService venueManageExhibitionSpaceService;

    @Resource
    private VenueManageExhibitorService venueManageExhibitorService;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ServiceProviderSpace> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(ServiceProviderSpace model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        return R.successDef();
    }

    @Override
    public R<List<ServiceProviderSpaceVO>> queryExhibitionManageDetail(ServiceProviderSpaceQuery serviceProviderSpaceQuery) {
        // 服务商id
        Long serviceProviderId = serviceProviderSpaceQuery.getServiceProviderId();
        // 展会id
        Long exhibitionManageId = serviceProviderSpaceQuery.getExhibitionManageId();
        ExhibitionManage exhibitionManage = exhibitionManageService.getById(exhibitionManageId);
        Long exhibitionId =Objects.nonNull(exhibitionManage)? exhibitionManage.getVbExhibitionId():null;
        List<ExhibitionServiceProvider> list = exhibitionServiceProviderService.list(new QueryWrapper<ExhibitionServiceProvider>().lambda()
                .eq(ExhibitionServiceProvider::getServiceProviderId, serviceProviderId)
                .eq(ExhibitionServiceProvider::getExhibitionManageId, exhibitionManageId)
                .eq(ExhibitionServiceProvider::getIsDeleted, BusinessConstant.NO));
        List<Long> ids = list.stream().map(ExhibitionServiceProvider::getId).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(ids)) {
            List<ServiceProviderSpace> providerSpaces = list(new QueryWrapper<ServiceProviderSpace>().lambda().in(ServiceProviderSpace::getExhibitionServiceProviderId, ids).eq(ServiceProviderSpace::getIsDeleted, BusinessConstant.NO));
            List<ServiceProviderSpaceVO> serviceProviderSpaceDTOS = ConvertUtil.convertList(providerSpaces, ServiceProviderSpaceVO.class);
            List<ExhibitionSpaceVO> data = venueManageExhibitionSpaceService.queryByExhibitionId(exhibitionId);
            Map<Long, ExhibitionSpaceVO> exhibitionSpaceVOMap = data.stream().collect(Collectors.toMap(ExhibitionSpaceVO::getSpaceId, Function.identity()));
            for (ServiceProviderSpaceVO serviceProviderSpaceVO : serviceProviderSpaceDTOS) {
                Long spaceId = serviceProviderSpaceVO.getSpaceId();
                ExhibitionSpaceVO exhibitionSpaceVO = exhibitionSpaceVOMap.get(spaceId);
                if(Objects.nonNull(exhibitionSpaceVO)){
                    serviceProviderSpaceVO.setSpaceName(exhibitionSpaceVO.getSpaceName());
                }
            }
            return R.success(serviceProviderSpaceDTOS);
        }else {
            return R.success(Collections.emptyList());
        }
    }

    @Override
    public List<ServiceProviderSpaceVO> queryByExhibitionId(Long exhibitionManageId, Long serviceProviderId) {
        ServiceProviderSpaceQuery serviceProviderSpaceQuery = new ServiceProviderSpaceQuery();
        serviceProviderSpaceQuery.setServiceProviderId(serviceProviderId);
        serviceProviderSpaceQuery.setExhibitionManageId(exhibitionManageId);
        R<List<ServiceProviderSpaceVO>> result = queryExhibitionManageDetail(serviceProviderSpaceQuery);
        return result.getData();
    }

    @Override
    public List<ExhibitionSpaceVO> queryExhibitionSpaceByExhibitionId(Long exhibitionManageId, Long serviceProviderId) {
        log.info("queryExhibitionSpaceByExhibitionId - 展会ID，服务商ID 查询服务商在展会中负责的展厅列表, exhibitionManageId={}, serviceProviderId={}", exhibitionManageId, serviceProviderId);
        // 展会ID查询展会下所有的展厅
        List<ExhibitionSpaceVO> exhibitionSpaceList = venueManageExhibitionSpaceService.listByExhibitionManageId(exhibitionManageId);
        if (exhibitionSpaceList == null || exhibitionSpaceList.isEmpty()) {
            return Collections.emptyList();
        }
        ServiceProvider serviceProvider = serviceProviderService.getById(serviceProviderId);
        if (serviceProvider == null) {
            return Collections.emptyList();
        }
        // 匹配服务商负责的展厅
        Map<String, ExhibitionSpaceVO> exhibitionSpaceMap = new HashMap<>(16);
        exhibitionSpaceList.forEach(exhibitionSpaceVO -> exhibitionSpaceMap.put(exhibitionSpaceVO.getSpaceCode(), exhibitionSpaceVO));
        List<ExhibitionSpaceVO> serviceProviderExhibitionSpaceList;
        Set<String> distinctSet = new HashSet<>(16);
        if (ServiceProviderTypeEnum.BUILD_SERVICE_PROVIDER.eq(serviceProvider.getServiceProviderType())) {
            // 查询搭建商的展位
            ExhibitorDTO exhibitorDTO = new ExhibitorDTO();
            exhibitorDTO.setExhibitionManageId(exhibitionManageId);
            exhibitorDTO.setBuilderId(serviceProviderId);
            List<ExhibitorVO> exhibitorList = venueManageExhibitorService.queryExhibitors(exhibitorDTO);
            if (exhibitorList == null || exhibitorList.isEmpty()) {
                return Collections.emptyList();
            }
            // 匹配过滤出展厅
            serviceProviderExhibitionSpaceList = exhibitorList
                    .stream()
                    .map(exhibitorVO -> {
                        if (StrUtil.isNotBlank(exhibitorVO.getSpaceCode())) {
                            return exhibitionSpaceMap.get(exhibitorVO.getSpaceCode());
                        } else {
                            return null;
                        }
                    })
                    .filter(Objects::nonNull)
                    .filter(exhibitionSpaceVO -> distinctSet.add(exhibitionSpaceVO.getSpaceCode()))
                    .collect(Collectors.toList());
        } else {
            // 查询服务商与展厅关系列表
            List<ServiceProviderSpaceVO> serviceProviderSpaceList = queryByExhibitionId(exhibitionManageId, serviceProviderId);
            if (serviceProviderSpaceList == null || serviceProviderSpaceList.isEmpty()) {
                return Collections.emptyList();
            }
            // 匹配过滤出展厅
            serviceProviderExhibitionSpaceList = serviceProviderSpaceList
                    .stream()
                    .map(serviceProviderSpaceVO -> exhibitionSpaceMap.get(serviceProviderSpaceVO.getSpaceCode()))
                    .filter(Objects::nonNull)
                    .filter(exhibitionSpaceVO -> distinctSet.add(exhibitionSpaceVO.getSpaceCode()))
                    .collect(Collectors.toList());
        }
        return serviceProviderExhibitionSpaceList;
    }

    @Override
    public List<String> querySpaceCodeListByExhibitionId(Long exhibitionManageId, Long serviceProviderId) {
        List<ServiceProviderSpaceVO> serviceProviderSpaceList = queryByExhibitionId(exhibitionManageId, serviceProviderId);
        if (serviceProviderSpaceList == null || serviceProviderSpaceList.isEmpty()) {
           return Collections.emptyList();
        }
        return serviceProviderSpaceList
                .stream()
                .map(ServiceProviderSpaceVO::getSpaceCode)
                .collect(Collectors.toList());
    }

    @Override
    public boolean removeBatchByExhibitionServiceProviderId(List<Long> exhibitionServiceProviderIdList) {
        log.info("removeBatchByExhibitionServiceProviderId - 展会服务商关系ID批量删除服务商展厅关系, exhibitionServiceProviderIdList={}", exhibitionServiceProviderIdList);
        if (exhibitionServiceProviderIdList == null || exhibitionServiceProviderIdList.isEmpty()) {
            return false;
        }
        LambdaUpdateWrapper<ServiceProviderSpace> updateWrapper = new UpdateWrapper<ServiceProviderSpace>()
                .lambda()
                .in(ServiceProviderSpace::getExhibitionServiceProviderId, exhibitionServiceProviderIdList)
                .set(ServiceProviderSpace::getIsDeleted, BusinessConstant.YES);
        return update(updateWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveServiceProviderSpace(ServiceProviderSpaceDTO serviceProviderSpaceDTO) {
        ServiceProviderSpace serviceProviderSpace = BeanUtil.copyProperties(serviceProviderSpaceDTO, ServiceProviderSpace.class, "id");
        return save(serviceProviderSpace);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveBatch(List<ServiceProviderSpaceDTO> serviceProviderSpaceDTOList, Long exhibitionServiceProviderId) {
        if (serviceProviderSpaceDTOList == null || serviceProviderSpaceDTOList.isEmpty()) {
            return false;
        }
        for (ServiceProviderSpaceDTO serviceProviderSpaceDTO : serviceProviderSpaceDTOList) {
            serviceProviderSpaceDTO.setExhibitionServiceProviderId(exhibitionServiceProviderId);
            saveServiceProviderSpace(serviceProviderSpaceDTO);
        }
        return true;
    }

    @Override
    public List<ServiceProviderSpaceVO> queryServiceProviderAllSpace(ServiceProviderSpaceQuery serviceProviderSpaceQuery) {
        return baseMapper.queryServiceProviderAllSpace(serviceProviderSpaceQuery);
    }
}
